/* eslint-disable no-bitwise */

export function utf16to8(str:string) {
    let out ='';
    let i=0;
    let l=0;
    let c=0;
    out = '';
    l = str.length;
    for (i = 0; i < l; i++) {
        c = str.charCodeAt(i);
        if (c <= 0x7f) {
            out += String.fromCharCode(c);
        } else if (c <= 0x7ff) {
            out += String.fromCharCode(0xc0 | c >> 6);
            out += String.fromCharCode(0x80 | c & 0x1f);
        } else {
            out += String.fromCharCode(0xe0 | c >> 12);
            out += String.fromCharCode(0x80 | c >> 6 & 0x3f);
            out += String.fromCharCode(0x80 | c & 0x3f);
        }
    }
    return out;
}



// export const str2utf8 = window.TextEncoder ? function(str:string) {
//     const encoder = new TextEncoder('utf8');
//     const bytes = encoder.encode(str);
//     let result = '';
//     for(let i = 0; i < bytes.length; ++i) {
//         result += String.fromCharCode(bytes[i]);
//     }
//     return result;
// } : function(str :string) {
//     return eval('\''+encodeURI(str).replace(/%/gm, '\\x')+'\'');
// };

const base64Charset = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
// 1. 每3字节一组，一共24个二进制位
// 2. 将24个二进制位分4组，每组6个二进制位
// 3. 每组前补两个0，得到4个字节，一共32个二进制位
// 4. 将每个字节作为下标从下列字符集中获取字符
//
// 处理两字节的情况：
// 分三组，第3组前后各补2个0，用=代替缺少的第4组
//
// 处理一字节的情况：
// 分两组，第2组前补2个0、后补4个0，用==代替缺少的第3和第4组
export function encodeBase64(str: string) {
    let out = '';
    let c1 = 0;
    let c2 = 0;
    let c3 = 0;
    let g1 = 0;
    let g2 = 0;
    let g3 = 0;
    let g4 = 0;
    out = '';
    let i = 0;
    str = utf16to8(str);
    const l = str.length;
    while (i < l) {
        c1 = str.charCodeAt(i++);
        c2 = str.charCodeAt(i++);
        c3 = str.charCodeAt(i++);
        g1 = c1 >> 2;
        g2 = (c1 & 0x3) << 4 | c2 >> 4;
        g3 = (c2 & 0xf) << 2 | c3 >> 6;
        g4 = c3 & 0x3f;
        if (!c2) {
            g3 = g4 = 64;
        } else if (!c3) {
            g4 = 64;
        }
        out += base64Charset.charAt(g1) + base64Charset.charAt(g2) + base64Charset.charAt(g3) + base64Charset.charAt(g4);
    }
    return out;
}
